<template>
  <div class="property-editor">
    <!-- 字符串输入 -->
    <el-input
      v-if="property.type === 'string'"
      v-model="localValue"
      :placeholder="property.placeholder || `请输入${property.label}`"
      :disabled="property.disabled"
      size="small"
      @input="handleInput"
      @change="handleChange"
    />
    
    <!-- 数字输入 -->
    <el-input-number
      v-else-if="property.type === 'number'"
      v-model="localValue"
      :min="property.min"
      :max="property.max"
      :step="property.step || 1"
      :precision="property.precision || 0"
      :disabled="property.disabled"
      size="small"
      @change="handleChange"
    />
    
    <!-- 布尔选择 -->
    <el-switch
      v-else-if="property.type === 'boolean'"
      v-model="localValue"
      :disabled="property.disabled"
      @change="handleChange"
    />
    
    <!-- 选择器 -->
    <el-select
      v-else-if="property.type === 'select'"
      v-model="localValue"
      :placeholder="property.placeholder || `请选择${property.label}`"
      :disabled="property.disabled"
      size="small"
      @change="handleChange"
    >
      <el-option
        v-for="option in property.options"
        :key="option.value"
        :label="option.label"
        :value="option.value"
      />
    </el-select>
    
    <!-- 颜色选择器 -->
    <el-color-picker
      v-else-if="property.type === 'color'"
      v-model="localValue"
      :disabled="property.disabled"
      size="small"
      @change="handleChange"
    />
    
    <!-- 文本域 -->
    <el-input
      v-else-if="property.type === 'textarea'"
      v-model="localValue"
      type="textarea"
      :rows="property.rows || 3"
      :placeholder="property.placeholder || `请输入${property.label}`"
      :disabled="property.disabled"
      size="small"
      @input="handleInput"
      @change="handleChange"
    />
    
    <!-- 滑块 -->
    <el-slider
      v-else-if="property.type === 'slider'"
      v-model="localValue"
      :min="property.min || 0"
      :max="property.max || 100"
      :step="property.step || 1"
      :disabled="property.disabled"
      :show-tooltip="true"
      @change="handleChange"
    />
    
    <!-- 日期选择器 -->
    <el-date-picker
      v-else-if="property.type === 'date'"
      v-model="localValue"
      :type="property.dateType || 'date'"
      :placeholder="property.placeholder || `请选择${property.label}`"
      :disabled="property.disabled"
      size="small"
      @change="handleChange"
    />
    
    <!-- 时间选择器 -->
    <el-time-picker
      v-else-if="property.type === 'time'"
      v-model="localValue"
      :placeholder="property.placeholder || `请选择${property.label}`"
      :disabled="property.disabled"
      size="small"
      @change="handleChange"
    />
    
    <!-- 图标选择器 -->
    <div
      v-else-if="property.type === 'icon'"
      class="icon-selector"
      @click="showIconSelector = true"
    >
      <el-input
        v-model="localValue"
        :placeholder="property.placeholder || `请选择${property.label}`"
        :disabled="property.disabled"
        size="small"
        readonly
      >
        <template #suffix>
          <i :class="localValue || 'el-icon-picture-outline'" />
        </template>
      </el-input>
    </div>
    
    <!-- 文件上传 -->
    <el-upload
      v-else-if="property.type === 'file'"
      :file-list="fileList"
      :disabled="property.disabled"
      size="small"
      @change="handleFileChange"
    >
      <el-button size="small" type="primary">选择文件</el-button>
    </el-upload>
    
    <!-- 对象编辑器 -->
    <div
      v-else-if="property.type === 'object'"
      class="object-editor"
    >
      <div
        v-for="(subProp, key) in property.properties"
        :key="key"
        class="sub-property"
      >
        <label class="sub-property-label">{{ subProp.label }}</label>
        <PropertyEditor
          :property="subProp"
          :value="getSubPropertyValue(key)"
          @change="handleSubPropertyChange(key, $event)"
        />
      </div>
    </div>
    
    <!-- 数组编辑器 -->
    <div
      v-else-if="property.type === 'array'"
      class="array-editor"
    >
      <div class="array-header">
        <span class="array-title">{{ property.label }}</span>
        <el-button
          size="small"
          icon="el-icon-plus"
          @click="addArrayItem"
        >
          添加
        </el-button>
      </div>
      
      <div
        v-for="(item, index) in localValue"
        :key="index"
        class="array-item"
      >
        <PropertyEditor
          :property="property.itemSchema"
          :value="item"
          @change="handleArrayItemChange(index, $event)"
        />
        <el-button
          size="small"
          icon="el-icon-delete"
          type="danger"
          @click="removeArrayItem(index)"
        />
      </div>
    </div>
    
    <!-- 默认文本输入 -->
    <el-input
      v-else
      v-model="localValue"
      :placeholder="property.placeholder || `请输入${property.label}`"
      :disabled="property.disabled"
      size="small"
      @input="handleInput"
      @change="handleChange"
    />
    
    <!-- 图标选择器弹窗 -->
    <el-dialog
      v-model="showIconSelector"
      title="选择图标"
      width="600px"
      :close-on-click-modal="false"
    >
      <div class="icon-grid">
        <div
          v-for="icon in availableIcons"
          :key="icon"
          class="icon-item"
          :class="{ active: localValue === icon }"
          @click="selectIcon(icon)"
        >
          <i :class="icon" />
          <span class="icon-name">{{ icon }}</span>
        </div>
      </div>
      
      <template #footer>
        <el-button @click="showIconSelector = false">取消</el-button>
        <el-button type="primary" @click="confirmIconSelection">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'

// Props
const props = defineProps({
  property: {
    type: Object,
    required: true
  },
  value: {
    type: [String, Number, Boolean, Array, Object],
    default: null
  }
})

// Emits
const emit = defineEmits(['change'])

// 响应式状态
const localValue = ref(props.value)
const showIconSelector = ref(false)
const fileList = ref([])

// 监听外部值变化
watch(() => props.value, (newValue) => {
  localValue.value = newValue
}, { deep: true })

// 计算属性
const availableIcons = computed(() => {
  return [
    'el-icon-edit',
    'el-icon-delete',
    'el-icon-plus',
    'el-icon-minus',
    'el-icon-close',
    'el-icon-check',
    'el-icon-search',
    'el-icon-refresh',
    'el-icon-download',
    'el-icon-upload',
    'el-icon-picture',
    'el-icon-video-camera',
    'el-icon-mic',
    'el-icon-location',
    'el-icon-star-on',
    'el-icon-heart',
    'el-icon-user',
    'el-icon-setting',
    'el-icon-more',
    'el-icon-arrow-left',
    'el-icon-arrow-right',
    'el-icon-arrow-up',
    'el-icon-arrow-down'
  ]
})

// 方法
const handleInput = (value) => {
  localValue.value = value
}

const handleChange = (value) => {
  localValue.value = value
  emit('change', value)
}

const handleFileChange = (file, fileList) => {
  fileList.value = fileList
  emit('change', fileList)
}

const getSubPropertyValue = (key) => {
  if (!localValue.value || typeof localValue.value !== 'object') {
    return props.property.properties[key]?.default || null
  }
  return localValue.value[key] ?? (props.property.properties[key]?.default || null)
}

const handleSubPropertyChange = (key, value) => {
  if (!localValue.value || typeof localValue.value !== 'object') {
    localValue.value = {}
  }
  localValue.value[key] = value
  emit('change', localValue.value)
}

const addArrayItem = () => {
  if (!Array.isArray(localValue.value)) {
    localValue.value = []
  }
  
  const newItem = props.property.itemSchema?.default || null
  localValue.value.push(newItem)
  emit('change', localValue.value)
}

const removeArrayItem = (index) => {
  if (Array.isArray(localValue.value)) {
    localValue.value.splice(index, 1)
    emit('change', localValue.value)
  }
}

const handleArrayItemChange = (index, value) => {
  if (Array.isArray(localValue.value)) {
    localValue.value[index] = value
    emit('change', localValue.value)
  }
}

const selectIcon = (icon) => {
  localValue.value = icon
}

const confirmIconSelection = () => {
  emit('change', localValue.value)
  showIconSelector.value = false
}
</script>

<style scoped>
.property-editor {
  width: 100%;
}

.icon-selector {
  cursor: pointer;
}

.object-editor {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 8px;
  background: #fafafa;
}

.sub-property {
  margin-bottom: 8px;
}

.sub-property:last-child {
  margin-bottom: 0;
}

.sub-property-label {
  display: block;
  font-size: 11px;
  color: #909399;
  margin-bottom: 4px;
}

.array-editor {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 8px;
  background: #fafafa;
}

.array-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.array-title {
  font-size: 12px;
  font-weight: 500;
  color: #606266;
}

.array-item {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  padding: 8px;
  background: white;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
}

.array-item:last-child {
  margin-bottom: 0;
}

.array-item .property-editor {
  flex: 1;
}

.icon-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 12px;
  max-height: 400px;
  overflow-y: auto;
}

.icon-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s;
}

.icon-item:hover {
  border-color: #409eff;
  background: #f0f9ff;
}

.icon-item.active {
  border-color: #409eff;
  background: #e6f7ff;
}

.icon-item i {
  font-size: 24px;
  color: #606266;
}

.icon-name {
  font-size: 11px;
  color: #909399;
  text-align: center;
  word-break: break-all;
}
</style>
